package com.zhl.common.aspect;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zhl.common.annotation.AutoLog;
import com.zhl.common.holder.RequestHolder;
import com.zhl.model.log.entity.SysLog;
import com.zhl.model.log.service.ISysLogService;
import com.zhl.model.sys.user.entity.User;
import com.zhl.util.*;
import eu.bitwalker.useragentutils.Browser;
import eu.bitwalker.useragentutils.Version;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Arrays;


/**
 * 系统日志，切面处理类
 *
 * @author zhouhailong
 * @email
 * @date 2019年12月27日
 */
@Aspect
@Component
@Slf4j
@ConditionalOnProperty(name = "logging.operate.all",havingValue = "false")
public class AutoLogAspect {

	@Autowired
	private ISysLogService sysLogService;

	private static ThreadLocal<ProceedingJoinPoint> proceedingJoinPointThreadLocal = new ThreadLocal<>();

	@Pointcut("@annotation(com.zhl.common.annotation.AutoLog)")
	public void logPointCut() {
		// 该方法无方法体,主要为了让同类中其他方法使用此切入点
	}

	@Around("logPointCut()")
	public Object around(ProceedingJoinPoint point) throws Throwable {
		proceedingJoinPointThreadLocal.set(point);
		long beginTime = System.currentTimeMillis();
		//执行方法
		Object result = point.proceed();
		//执行时长(毫秒)
		Long time = System.currentTimeMillis() - beginTime;
		//保存日志
		SysLog sysLog = new SysLog();
		// 返回结果
		sysLog.setResponseDetail(JSON.toJSONString(result));
		sysLogService.asyncSaveLog(point,time, sysLog);
		return result;
	}


	@AfterThrowing(pointcut="logPointCut()",throwing = "exception")
	public void afterThrowing(Exception exception){
		ProceedingJoinPoint proceedingJoinPoint = proceedingJoinPointThreadLocal.get();
		HttpServletRequest request = RequestHolder.getRequest();
		SysLog sysLog = new SysLog();
		// 异常信息
		sysLog.setExceptionDetail(JSON.toJSONString(exception));
		sysLogService.asyncSaveLog(proceedingJoinPoint,null, sysLog);
	}
}
